Namespace GUI

    Module mAnimation

        Friend Class Animation

            Public mLib As EvoLib.Protocol.ImgLibs
            Public mStartImg As Integer
            Public mImgCount As Integer
            Public mTickLength As Integer
            Public mDrawMode As Globals.DrawingMode
            Public mBlendVal As Single
            Public mTint As Integer
            Public mOffsetX As Integer
            Public mOffsetY As Integer
            Public mSound As String

            Public Sub New(ByRef imglib As EvoLib.Protocol.ImgLibs, ByRef startimg As Integer, ByRef count As Integer, _
                        ByRef speed As Integer, Optional ByRef mode As Globals.DrawingMode = Globals.DrawingMode.Normal, _
                        Optional ByRef blend As Single = 1.0, Optional ByRef sound As String = "", Optional ByRef offx As Integer = 0, Optional ByRef offy As Integer = 0, Optional ByRef tint As Integer = -1)

                mLib = imglib
                mStartImg = startimg
                mImgCount = count
                mTickLength = speed
                mDrawMode = mode
                mBlendVal = blend
                mTint = tint

                mOffsetX = offx
                mOffsetY = offy

                mSound = sound

            End Sub

            Protected Overrides Sub Finalize()
                MyBase.Finalize()
            End Sub

        End Class

        Friend Class CustomEffect

            Public mMode As Globals.DrawingMode
            Public mBlend As Single
            Public mTint As Color
            Public mFreezeFrame As Integer
            Public mSpeed As Integer

            Public Sub New(ByRef mode As Globals.DrawingMode, ByRef blendval As Single, ByRef tint As Color, Optional ByRef speed As Integer = -1, Optional ByRef freezeframe As Integer = -1)

                mMode = mode
                mBlend = blendval
                mTint = tint
                mFreezeFrame = freezeframe
                mSpeed = speed

            End Sub

        End Class

    End Module

    Friend Class MirAnimation
        Implements Windows.GUIObj

        Dim mWnd As MirWindow

        Dim mName As String
        Public PosX As Integer, PosY As Integer

        Public mCurrentAnim As Animation
        Dim mLoop As Boolean

        Dim mCaptureClicks As Boolean
        Dim mClientRect As Rectangle
        Dim mIsVisible As Boolean
        Dim mAnimating As Boolean
        Dim mLastImg As Integer

        Dim mCustomEffect As CustomEffect = Nothing

        Public mAlphaColor As Color

        Public Event Click(ByVal name As String)
        Public Event AnimStopped(ByVal name As String)
        Public Event AnimLooping()
        Public Event LostFocus()
        Public Event MouseEvent(ByRef type As Mouse.MouseInputType, ByRef e As MouseEventArgs, ByVal name As String)

        Private offx As Integer
        Private offy As Integer

        Public Sub New(ByRef wnd As MirWindow, ByRef name As String, ByRef x As Integer, ByRef y As Integer, _
                        Optional ByRef captureclicks As Boolean = True)

            mWnd = wnd
            mName = name
            PosX = x
            PosY = y
            mCaptureClicks = captureclicks

            CalcClientRect()

            mIsVisible = True

            wnd.AddInterfaceItem(Me)

        End Sub

        Public Sub MouseInput(ByRef type As Mouse.MouseInputType, ByRef e As MouseEventArgs) Implements Windows.mWindows.GUIObj.MouseInput

            Select Case type

                Case Mouse.MouseInputType.MouseClick
                    Windows.FocusInterface(Nothing)
                    RaiseEvent Click(mName)

            End Select

            RaiseEvent MouseEvent(type, e, mName)

        End Sub

        Public Function CurrentImg() As Integer
            'If Not mCustomEffect Is Nothing Then
            'If mCustomEffect.mFreezeFrame > -1 Then
            'Return mCurrentAnim.mStartImg + mCustomEffect.mFreezeFrame
            'End If
            'End If

            If mCurrentAnim Is Nothing Then Exit Function

            If mAnimating Then
                Dim tmr As Integer = Timers.GetTimer(TimerName)
                If tmr = mCurrentAnim.mImgCount Then
                    If mLoop Then
                        Timers.RemoveTimer(TimerName)
                        Timers.AddTimer(TimerName, mCurrentAnim.mTickLength, mCurrentAnim.mImgCount)
                        RaiseEvent AnimLooping()
                        Return mCurrentAnim.mStartImg
                    Else
                        'Dim tmp As Integer = mCurrentAnim.mStartImg
                        StopAnim()
                        RaiseEvent AnimStopped(mName)
                        Return mCurrentAnim.mStartImg + tmr - 1
                    End If
                Else
                    Return mCurrentAnim.mStartImg + tmr
                End If
            Else
                Return mCurrentAnim.mStartImg + mCurrentAnim.mImgCount - 1
            End If

        End Function

        Public ReadOnly Property TimerName() As String
            Get
                Return mName & "Timer"
            End Get
        End Property

        Private Sub CalcClientRect()

            If mCaptureClicks And Not mCurrentAnim Is Nothing Then
                With Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg)
                    mClientRect = New Rectangle(PosX + .Header.OffsetX + mCurrentAnim.mOffsetX, PosY + .Header.OffsetY + mCurrentAnim.mOffsetY, .Header.Width, .Header.Height)
                End With
            Else
                mClientRect = Rectangle.Empty
            End If

        End Sub

        Public Function Contains(ByRef x As Integer, ByRef y As Integer) As Boolean Implements Windows.GUIObj.Contains

            CalcClientRect()

            If mClientRect = Rectangle.Empty Or mCurrentAnim Is Nothing Then Return False
            With Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg)

                If mClientRect.Contains(x, y) Then

                    If TexContains(Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg).Texture, x - mClientRect.Left, y - mClientRect.Top) Then
                        Return True
                    Else
                        If Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg).Texture2 Is Nothing Then
                            Return False
                        Else
                            Return TexContains(Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg).Texture2, x - mClientRect.Left, y - mClientRect.Top)
                        End If
                    End If

                End If

            End With

        End Function

        Private Function TexContains(ByRef tex As Microsoft.DirectX.Direct3D.Texture, ByRef x As Integer, ByRef y As Integer) As Boolean

            If tex Is Nothing Then Return False

            Dim ranks() As Integer = {4}
            Dim arr() As Byte = tex.LockRectangle(GetType(Byte), 0, New Rectangle(x, y, 1, 1), Microsoft.DirectX.Direct3D.LockFlags.ReadOnly, ranks)
            tex.UnlockRectangle(0)

            If arr(0) > 0 And arr(1) > 0 And arr(2) > 0 Then
                Return True
            Else
                Return False
            End If

        End Function

        Public Sub Draw(ByRef mode As Globals.DrawingMode, ByRef x As Integer, ByRef y As Integer, ByRef z As Single) Implements Windows.mWindows.GUIObj.Draw

            If Not mIsVisible Or mCurrentAnim Is Nothing Then Exit Sub

            If Not (mCurrentAnim.mDrawMode = mode Or mode = Globals.DrawingMode.Tinted) Then Exit Sub

            If CurrentImg() <> mLastImg Then CalcClientRect()

            If CurrentImg() = mCurrentAnim.mStartImg And Not mLastImg = CurrentImg() Then
                'RaiseEvent AnimStarting()
                If mCurrentAnim.mSound.Length > 0 Then Sound.PlaySoundEffect(mCurrentAnim.mSound, 100)
            End If
            mLastImg = CurrentImg()

            'If Not mCustomEffect Is Nothing Then

            'Engine.SetDrawMode(mCustomEffect.mMode, mCustomEffect.mBlend, mCustomEffect.mTint.ToArgb)

            'If mCustomEffect.mFreezeFrame = -1 Then

            'With Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg)

            '.Draw(x + mPosX + .Header.OffsetX + mCurrentAnim.mOffsetX, y + mPosY + .Header.OffsetY + mCurrentAnim.mOffsetY, z)
            '.DrawAlpha(x + mPosX + .Header.OffsetX + mCurrentAnim.mOffsetX, y + mPosY + .Header.OffsetY + mCurrentAnim.mOffsetY, z)

            'End With

            'Exit Sub

            'End If

            'Else
            'Engine.SetDrawMode(mCurrentAnim.mDrawMode, mCurrentAnim.mBlendVal)
            'End If


            With Libs.GetLib(mCurrentAnim.mLib).Image(CurrentImg)

                If mode = Globals.DrawingMode.Tinted Then

                    DirectX.GameSprite.Begin(Microsoft.DirectX.Direct3D.SpriteFlags.AlphaBlend)
                    Engine.SetDrawModeTinted(1.0, mAlphaColor)
                    .DrawAlpha(x + offx + PosX + .Header.OffsetX + mCurrentAnim.mOffsetX, y + offy + PosY + .Header.OffsetY + mCurrentAnim.mOffsetY, z)
                    DirectX.GameSprite.End()

                ElseIf mode = Globals.DrawingMode.Shadow Then

                    DirectX.GameSprite.Begin(Microsoft.DirectX.Direct3D.SpriteFlags.AlphaBlend)
                    Engine.SetDrawModeShadow(Globals.ShadowBlend)
                    .Draw(x + offx + PosX + .Header.OffsetX + mCurrentAnim.mOffsetX, y + offy + PosY + .Header.OffsetY + mCurrentAnim.mOffsetY, z)
                    DirectX.GameSprite.End()

                Else

                    If mCurrentAnim.mDrawMode = mode Then .Draw(x + offx + PosX + .Header.OffsetX + mCurrentAnim.mOffsetX, y + offy + PosY + .Header.OffsetY + mCurrentAnim.mOffsetY, z)

                End If

            End With
            'Engine.RestorePrevDrawMode()
            'Engine.SetDrawMode(Globals.DrawingMode.Normal)

        End Sub

        Public Property Visible() As Boolean
            Get
                Return mIsVisible
            End Get
            Set(ByVal value As Boolean)
                mIsVisible = value
            End Set
        End Property

        Public Sub StartAnim(ByRef anim As Animation, ByRef looping As Boolean, Optional ByRef alphacol As Integer = -1, Optional ByRef startframe As Integer = 0)

            If anim Is Nothing Then mCurrentAnim = Nothing : Exit Sub

            StopAnim()

            mCustomEffect = Nothing
            mCurrentAnim = anim
            mAlphaColor = Color.FromArgb(alphacol)
            mLoop = looping
            mLastImg = -1

            'If mLoop Then
            If startframe >= anim.mImgCount Then startframe = 0

            Timers.AddTimer(TimerName, mCurrentAnim.mTickLength, mCurrentAnim.mImgCount, , startframe)
            'Else
            'Timers.AddTimer(TimerName, mCurrentAnim.mTickLength, mCurrentAnim.mImgCount)
            'End If

            mAnimating = True

        End Sub

        'Public Sub StartAnimCustomEffect(ByRef anim As Animation, ByRef looping As Boolean, ByRef effect As CustomEffect, Optional ByRef alphacol As Integer = -1)

        'If anim Is Nothing Then Exit Sub

        'StopAnim()

        'Dim mcustomspeed As Integer

        'mCurrentAnim = anim
        'mAlphaCol = Color.FromArgb(alphacol)
        'mCustomEffect = effect
        'mLoop = looping

        'If effect.mFreezeFrame = -1 Then

        'If effect.mSpeed = -1 Then
        'mcustomspeed = mCurrentAnim.mTickLength
        'Else
        'mcustomspeed = effect.mSpeed
        'End If

        'If mLoop Then
        'Timers.AddTimer(TimerName, mcustomspeed, mCurrentAnim.mImgCount)
        'Else
        'Timers.AddTimer(TimerName, mcustomspeed, mCurrentAnim.mImgCount)
        'End If

        'End If

        'mAnimating = True

        'End Sub

        Public Sub StopAnim()
            Try
                Timers.RemoveTimer(TimerName)
            Catch
            End Try
            mAnimating = False
            'mCurrentAnim = Nothing
        End Sub

        Public Sub Focus() Implements Windows.mWindows.GUIObj.Focus

        End Sub

        Public Sub KeyboardInput(ByRef type As Keyboard.mKeyboardVars.KeyboardInputType, ByRef e As System.Windows.Forms.KeyEventArgs) Implements Windows.mWindows.GUIObj.KeyboardInput

        End Sub

        Public Sub KeyboardInput(ByRef type As Keyboard.mKeyboardVars.KeyboardInputType, ByRef e As System.Windows.Forms.KeyPressEventArgs) Implements Windows.mWindows.GUIObj.KeyboardInput

        End Sub

        Public Event TabSwitch() Implements Windows.mWindows.GUIObj.TabSwitch

        Public Sub UnFocus() Implements Windows.mWindows.GUIObj.UnFocus
            RaiseEvent LostFocus()
        End Sub

        Public Sub Destroy() Implements Windows.mWindows.GUIObj.Destroy
            StopAnim()
            mWnd.RemoveInterfaceItem(Me)
        End Sub

        Public ReadOnly Property GetsFocus() As Boolean Implements Windows.mWindows.GUIObj.GetsFocus
            Get
                Return False
            End Get
        End Property

        Public Sub SetPos(ByRef x As Integer, ByRef y As Integer) Implements Windows.mWindows.GUIObj.SetPos
            PosX = x
            PosY = y
        End Sub

        Public ReadOnly Property ParentWin() As MirWindow Implements Windows.mWindows.GUIObj.ParentWin
            Get
                Return mWnd
            End Get
        End Property

        Public ReadOnly Property Name() As String Implements Windows.mWindows.GUIObj.Name
            Get
                Return mName
            End Get
        End Property

        Public Sub ReloadSurafces() Implements Windows.mWindows.GUIObj.ReloadSurafces

        End Sub
    End Class

End Namespace